package org.example.common.security.interceptor;

import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils;
import org.example.common.base.constants.SecurityConstants;
import org.example.common.base.context.SecurityContextHolder;
import org.example.common.base.util.web.ServletUtils;
import org.example.common.security.auth.AuthUtil;
import org.example.common.security.util.SecurityUtils;
import org.example.system.api.entity.LoginUser;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @version 1.0.0
 * @className: HeaderInterceptor
 * @description: 自定义请求头拦截器，将Header数据封装到线程变量中方便获取
 * @author: LiJunYi
 * @create: 2022/8/2 14:40
 */
public class HeaderInterceptor implements AsyncHandlerInterceptor
{
    /**
     * 在执行controller方法之前将请求头中的token信息解析出来，放入SecurityContextHolder中（TransmittableThreadLocal）
     * @param request  请求
     * @param response 响应
     * @param handler  处理程序
     * @return boolean
     * @throws Exception 异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        if (!(handler instanceof HandlerMethod))
        {
            return true;
        }

        SecurityContextHolder.setUserId(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USER_ID));
        SecurityContextHolder.setUserName(ServletUtils.getHeader(request, SecurityConstants.DETAILS_USERNAME));
        SecurityContextHolder.setUserKey(ServletUtils.getHeader(request, SecurityConstants.USER_KEY));

        String token = SecurityUtils.getToken();
        if (StringUtils.isNotEmpty(token))
        {
            LoginUser loginUser = AuthUtil.getLoginUser(token);
            if (ObjectUtil.isNotNull(loginUser))
            {
                AuthUtil.verifyLoginUserExpire(loginUser);
                SecurityContextHolder.set(SecurityConstants.LOGIN_USER, loginUser);
            }
        }
        return true;
    }

    /**
     * 在视图渲染之后执行，意味着一次请求结束，清除TTL中的身份信息
     *
     * @param request  请求
     * @param response 响应
     * @param handler  处理程序
     * @param ex       异常
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        SecurityContextHolder.remove();
    }
}
